package com.myproject.jdk8;

import org.junit.Test;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamTest {

    //1、构造流的几种常见方法
    @Test
    public void test1(){
        // 1. Individual values
        Stream stream = Stream.of("a", "b", "c");

        // 2. Arrays
        String [] strArray = new String[] {"a", "b", "c"};

        stream = Stream.of(strArray);
        stream = Arrays.stream(strArray);

        // 3. Collections
        List<String> list = Arrays.asList(strArray);
        stream = list.stream();
    }

    public void 最终操作(){}
    //2、流转换为其它数据结构
    @Test
    public void toArray(){
        Stream<String> stream = Stream.of("a", "b", "c");

        // 1. Array
        String[] strArray1 = stream.toArray(String[]::new);
        System.out.println(strArray1);
        System.out.println(strArray1.length);

        String [] strArray = new String[] {"a", "b", "c"};
        System.out.println(strArray);
        System.out.println(strArray.length);


        // 3. String
        //String str = stream.collect(Collectors.joining()).toString();

    }

    @Test
    public void toCollection(){
        // 2. Collection
        Stream<String> stream = Stream.of("a", "b", "c");
//        List<String> list1 = stream.collect(Collectors.toList());
//        System.out.println(list1);

//        Set set1 = stream.collect(Collectors.toSet());
//        System.out.println(set1);


//        List<String> list2 = stream.collect(Collectors.toCollection(ArrayList::new));
//        System.out.println(list2);



//        Stack stack1 = stream.collect(Collectors.toCollection(Stack::new));
//        System.out.println(stack1);

        //流只能执行一次结束操作
        /*stream.
                forEach(s -> {
                    System.out.println("p"+s);
                });
        Stack stack1 = stream.collect(Collectors.toCollection(Stack::new));*/


    }

    @Test
    public void forEach(){
        List<String> source = Arrays.asList("a","b","c");
//        List<String> output = source.stream().
//                map(String::toUpperCase).
//                collect(Collectors.toList());
//        System.out.println(output);


        source.stream().
                forEach(s -> {
                    System.out.println("p"+s);
                });
    }

    @Test
    public void reduce(){
        // 字符串连接，concat = "ABCD"
//        String concat = Stream.of("A", "B", "C", "D").reduce("qq", String::concat);
//        System.out.println(concat);
        // 求最小值，minValue = -3.0
//        double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
//        System.out.println(minValue);
//        Double d = new Double("5.5");

        // 求和，sumValue = 10, 有起始值

//        int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
//        System.out.println(sumValue);

        // 求和，sumValue = 10, 无起始值

//        int sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
//        System.out.println(sumValue);

        // 过滤，字符串连接，concat = "ace"

        String concat = Stream.of("a", "B", "c", "D", "e", "F").
                filter(x -> x.compareTo("Z") > 0).
                reduce("", String::concat);
        System.out.println(concat);

    }

    @Test
    public void max() throws Exception {

        BufferedReader br = new BufferedReader(new FileReader("D:\\SUService.log"));
        int longest = br.lines().
            mapToInt(String::length).
            max().
            getAsInt();

        br.close();

        System.out.println(longest);
    }

    @Test
    public void 中间操作(){

    }

    @Test
    public void map(){
        List<String> source = Arrays.asList("a","b","c");
//        List<String> output = source.stream().
//                map(String::toUpperCase).
//                collect(Collectors.toList());
//        System.out.println(output);
        List<String> output = source.stream().
                map(s -> {
                    System.out.println("p"+s);
                    return "p"+s;
                }).
                collect(Collectors.toList());
        System.out.println(output);
    }

    @Test
    public void map1(){
        Stream<List<Integer>> inputStream = Stream.of(
                Arrays.asList(1),
                Arrays.asList(2, 3),
                Arrays.asList(4, 5, 6)
                );

        Stream<Integer> outputStream = inputStream.
                flatMap((childList) -> childList.stream());

        System.out.println(outputStream.collect(Collectors.toList()));

    }



    @Test
    public void filter(){
        List<String> source = Arrays.asList("a","b","c");
//        List<String> output = source.stream().
//                map(String::toUpperCase).
//                collect(Collectors.toList());
//        System.out.println(output);


        List<String> list = source.stream()
                .filter(p->p.equals("c"))
                .collect(Collectors.toList());
        System.out.println(list);
    }

    //peek是中间操作版的 forEach?
    @Test
    public void peek(){
        List<String> list = Stream.of("one", "two", "three", "four")
            .filter(e -> e.length() > 3)
            .peek(e -> System.out.println("Filtered value: " + e))
            .map(String::toUpperCase)
            .peek(e -> System.out.println("Mapped value: " + e))
            .collect(Collectors.toList());
        System.out.println(list);

    }

    public static void print(String text) {

        // Java 8
        Optional.ofNullable(text).ifPresent(System.out::println);

        // Pre-Java 8
        /*if (text != null) {
            System.out.println(text);
        }*/
    }

    @Test
    public void test8(){
        String strA = " abcd ", strB = null;

        print(strA);

       /* print("");

        print(strB);*/
    }

    @Test
    public void test9(){
        String strA = " abcd ", strB = null;

        print(strA);

       /* print("");

        print(strB);*/
    }



    @Test
    public void test11(){

        List<Person> persons = new ArrayList();
        for (int i = 1; i <= 10000; i++) {
            Person person = new Person(i, "name" + i);
            persons.add(person);
        }

        List<String> personList2 = persons.stream().
            map(Person::getName).limit(10).skip(3).collect(Collectors.toList());

        System.out.println(personList2);

    }

    @Test
    public void test12(){
        List<Person> persons = new ArrayList();
        for (int i = 1; i <= 5; i++) {
            Person person = new Person(i, "name" + i);
            persons.add(person);
        }

        List<Person> personList2 = persons.stream().sorted((p1, p2) ->

                p1.getName().compareTo(p2.getName())).limit(2).collect(Collectors.toList());

        System.out.println(personList2);

    }
    
    @Test
    public void test13() throws Exception{
        BufferedReader br = new BufferedReader(new FileReader("D:\\SUService.log"));
        /*int longest = br.lines().
            mapToInt(String::length).
            max().
            getAsInt();

        br.close();

        System.out.println(longest);*/

        List<String> words = br.lines().
            flatMap(line -> Stream.of(line.split(" "))).
            filter(word -> word.length() > 0).
            map(String::toLowerCase).
            distinct().
            sorted().
            collect(Collectors.toList());

        br.close();

        System.out.println(words);


    }

}
